<script setup lang="ts">
import { R, SysUser, ChangePwdBody } from '@/interface/user';
import { useUserStore } from '@/store/userStore';
import { storeToRefs } from 'pinia';
import {
  SaveOutlined, UserOutlined, SolutionOutlined,
  PhoneOutlined, ClusterOutlined, UsergroupAddOutlined, LoadingOutlined,
  PlusOutlined
} from '@ant-design/icons-vue'
import { updateUserInfoApi, refreshTokenApi, changePwdApi } from '@/api/security'
import { UploadChangeParam, message } from 'ant-design-vue';
import Cookies from 'js-cookie'
import { pathRewrite } from '@/utils/request'
import { Rule } from 'ant-design-vue/es/form';
import { useGlobalStore } from '@/store/globalStore';

const userStore = useUserStore()
const globalStore = useGlobalStore()
const saveLoading = ref<boolean>(false)
const uploadImgLoading = ref<boolean>(false);
const fileList = ref([])

const { sysUser } = storeToRefs(userStore)

const userFormState = reactive<SysUser>({

})

const saveUserInfo = async (values: SysUser) => {
  try {
    saveLoading.value = true
    const { data: res }: { data: R<any> } = await updateUserInfoApi(values)
    if (res.code === 200) {
      const { data: res2 }: { data: R<any> } = await refreshTokenApi()
      if (res2.code === 200) {
        userStore.accessToken = res2.data.accessToken as string;
        userStore.sysUser = res2.data.sysUser;
        Cookies.set("accessToken", userStore.accessToken, {
          expires: (res2.data.expiresIn || 0) / 60 / 24, //分钟->天
        });
        message.success("保存成功");
      }
    }
  } catch (error) {
    message.error("保存失败");
  } finally {
    saveLoading.value = false
  }
};

const beforeUpload = (file: any) => {
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/webp';
  if (!isJpgOrPng) {
    message.error('请上传jpg、png、webp图片');
  }
  const isLt8M = file.size / 1024 / 1024 < 8;
  if (!isLt8M) {
    message.error('头像大小必须小于8MB!');
  }
  return isJpgOrPng && isLt8M;
};

const handleChange = async (info: UploadChangeParam) => {
  if (info.file.status === 'uploading') {
    uploadImgLoading.value = true;
    return;
  }
  if (info.file.status === 'done') {
    // Get this url from response in real world.
    let response = info.file.response;
    if (response.code === 200) {
      await saveUserInfo({
        avatar: response.data
      })
    }
    uploadImgLoading.value = false;
  }
  if (info.file.status === 'error') {
    uploadImgLoading.value = false;
    message.error('upload error');
  }
};

const validatePwd = async (_rule: Rule, value: string) => {
  if (value === '' || value === undefined) {
    return Promise.reject('请输入密码');
  } else {
    if (value.length < 6) {
      return Promise.reject('密码必须大于等于6位');
    }
    return Promise.resolve();
  }
};

const validateConfimPwd = async (_rule: Rule, value: string) => {
  if (value === '') {
    return Promise.reject('请输入确认密码');
  } else {
    if (changePwdFormState.password !== value) {
      return Promise.reject('确认密码和密码不一致');
    }
    return Promise.resolve();
  }
};
//修改密码部分
const changePwdFormState = reactive<ChangePwdBody>({})
const changePwdRules: Record<string, Rule[]> = {
  userName: [{ required: true, trigger: 'blur' }],
  password: [{ required: true, validator: validatePwd, trigger: 'blur' }],
  confirmPassword: [{ required: true, validator: validateConfimPwd, trigger: 'blur' }],
}
const changePwdLoading = ref<boolean>(false)

const changePwd = async (values: ChangePwdBody) => {
  try {
    changePwdLoading.value = true;
    const { data: res }: { data: R<any> } = await changePwdApi(values)
    if (res.code === 200) {
      message.success('密码修改成功')
      changePwdFormState.password = ''
      changePwdFormState.confirmPassword = ''
    } else {
      message.error(res.msg)
    }
  } catch (error: any) {
    message.error(error.msg)
  } finally {
    changePwdLoading.value = false;
  }
}

onMounted(() => {
  userFormState.nickName = sysUser.value.nickName
  userFormState.sex = sysUser.value.sex
  userFormState.phonenumber = sysUser.value.phonenumber
  userFormState.email = sysUser.value.email
  changePwdFormState.userName = sysUser.value.userName
})

</script>

<template>
  <div class="flex flex-wrap gap-6 p-3 overflow-y-auto dark:text-white h-screen w-full"
    :style="{ width: globalStore.isMobile ? 'calc(100% - 60px)' : '100%' }">
    <a-card title="个人信息" class="w-[300px] h-fit">
      <div class="text-center">
        <a-upload v-model:file-list="fileList" name="file" list-type="picture" :show-upload-list="false"
          :action="`${pathRewrite}/sys/upload/server`" :before-upload="beforeUpload" @change="handleChange"
          :max-count="1" :headers="{
      'Authorization': userStore.accessToken || Cookies.get('accessToken') || ''
    }">
          <a-avatar :size="88" :src="userStore.sysUser.avatar" v-if="userStore.sysUser.avatar">
          </a-avatar>
          <div v-else>
            <LoadingOutlined v-if="uploadImgLoading"></LoadingOutlined>
            <PlusOutlined v-else></PlusOutlined>
            <div class="ant-upload-text">Upload</div>
          </div>
        </a-upload>
      </div>

      <div class="mt-6">
        <div class="flex border-t-[1px] justify-between dark:border-gray-500 py-2 px-1">
          <div>
            <UserOutlined />
            <span class="px-1">账号</span>
          </div>
          <div>{{ sysUser.userName }}</div>
        </div>
        <div class="flex border-t-[1px] justify-between dark:border-gray-500 py-2 px-1">
          <div>
            <SolutionOutlined />
            <span class="px-1">用户名称</span>
          </div>
          <div>{{ sysUser.nickName }}</div>
        </div>
        <div class="flex border-t-[1px] justify-between dark:border-gray-500 py-2 px-1">
          <div>
            <i class="iconfont">&#xe813;</i>
            <span class="px-1">性别</span>
          </div>
          <div>{{ sysUser.sex === '1' ? '男' : '女' }}</div>
        </div>
        <div class="flex border-t-[1px] justify-between dark:border-gray-500 py-2 px-1">
          <div>
            <PhoneOutlined />
            <span class="px-1">手机号码</span>
          </div>
          <div>{{ sysUser.phonenumber }}</div>
        </div>
        <div class="flex border-t-[1px] justify-between dark:border-gray-500 py-2 px-1">
          <div>
            <i class="iconfont">&#xe908;</i>
            <span class="px-1">邮箱</span>
          </div>
          <div>{{ sysUser.email }}</div>
        </div>
        <div class="flex border-t-[1px] justify-between dark:border-gray-500 py-2 px-1">
          <div>
            <ClusterOutlined />
            <span class="px-1">部门</span>
          </div>
          <div>{{ sysUser.dept?.deptName }}</div>
        </div>
        <div class="flex border-t-[1px] justify-between dark:border-gray-500 py-2 px-1">
          <div>
            <UsergroupAddOutlined />
            <span class="px-1">所属角色</span>
          </div>
          <div>{{ sysUser.roles?.reduce((cur, pre, idx) => {
      return cur.concat(pre.roleName + (sysUser.roles && idx === sysUser.roles.length - 1 ? '' : ' | '))
    }, '') }}</div>
        </div>
        <div class="flex border-t-[1px] justify-between dark:border-gray-500 py-2">
          <div>
            <i class="iconfont">&#xeb2a;</i>
            <span class="px-1">最近登录日期</span>
          </div>
          <div>{{ sysUser.loginDate }}</div>
        </div>
        <div class="flex border-t-[1px] border-b-[1px] justify-between dark:border-gray-500 py-2">
          <div>
            <i class="iconfont">&#xeb2a;</i>
            <span class="px-1">创建日期</span>
          </div>
          <div>{{ sysUser.createTime }}</div>
        </div>
      </div>
    </a-card>

    <a-card title="基本信息" class="w-[500px] h-fit">
      <a-form :model="userFormState" name="basic" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }"
        autocomplete="off" @finish="saveUserInfo">
        <a-form-item label="用户名称" name="nickName" :rules="[{ required: true, message: '用户名称不能为空' }]">
          <a-input v-model:value="userFormState.nickName" />
        </a-form-item>
        <a-form-item label="性别" name="sex" :rules="[{ required: true, message: '请选择性别' }]">
          <a-radio-group v-model:value="userFormState.sex" :options="[
      { label: '女', value: '0' },
      { label: '男', value: '1' },
    ]" />
        </a-form-item>
        <a-form-item label="手机号" name="phonenumber" :rules="[{ required: true, message: '手机号不能为空' }]">
          <a-input v-model:value="userFormState.phonenumber" />
        </a-form-item>
        <a-form-item label="邮箱" name="email" :rules="[{ required: true, message: '邮箱不能为空' }]">
          <a-input v-model:value="userFormState.email" />
        </a-form-item>
        <a-form-item :wrapper-col="{ offset: 4, span: 20 }">
          <a-button type="primary" html-type="submit" class="flex items-center" :loading="saveLoading">
            <template #icon>
              <SaveOutlined />
            </template>
            保存
          </a-button>
        </a-form-item>
      </a-form>
    </a-card>

    <a-card title="修改密码" class="w-[500px] h-fit">
      <a-form :model="changePwdFormState" name="basic2" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }"
        autocomplete="off" @finish="changePwd" :rules="changePwdRules">
        <a-form-item label="账号" name="userName">
          <a-input v-model:value="changePwdFormState.userName" />
        </a-form-item>
        <a-form-item label="密码" name="password">
          <a-input v-model:value="changePwdFormState.password" type="password" />
        </a-form-item>
        <a-form-item label="确认密码" name="confirmPassword">
          <a-input v-model:value="changePwdFormState.confirmPassword" type="password" />
        </a-form-item>
        <a-form-item :wrapper-col="{ offset: 3, span: 16 }">
          <a-button type="primary" html-type="submit" class="flex items-center" :loading="changePwdLoading">
            <template #icon>
              <SaveOutlined />
            </template>
            修改
          </a-button>
        </a-form-item>
      </a-form>
    </a-card>
  </div>
</template>

<style scoped></style>